package cg.studio.algorithm.sort;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import org.junit.Test;
import org.junit.runner.manipulation.Sorter;

public class SorterTester
{
  private Random random = new Random();
  
  protected NumericSorter<Number> createSorter()
  {
    //return new RadixSorter();
    return new QuickSorter();
  }
  
  @Test
  public void testSort()
  {
    int badSortTimes = 0;
    for( int i=0; i<100; ++i )
    {
      List< Number > datas = getDatas();
      NumericSorter<Number> sorter = createSorter();
      Collection<Number> sorted = sorter.sort( datas );
      boolean isSorted = isSorted(datas, sorted);
      if( !isSorted )
      {
        logLine( "this is " + ( isSorted ? "" : "NOT " ) + "well sorted. " );
        logLine( "orginal datas: " );
        log( datas );
        logLine( "sorted datas: " );
        log( sorted );
      }
      
      if( !isSorted )
        ++badSortTimes;
    }
    logLine( "test 100 times, bad sorts: " + badSortTimes );
  }
  
  private List<Number> getDatas()
  {
    List<Number> datas = new ArrayList<Number>();
    Collections.addAll( datas, new Integer[]{22, 25, 156, 174, 310, 237, 433, 591, 701, 611} );
    
//    for( int i=0; i<10; ++i )
//      datas.add( random.nextInt( 1000 ) );
    return datas;
  }
  
  public static boolean isSorted( Collection< Number > orginalDatas, Collection< Number > sortedDatas )
  {
    //check size are same;
    if( orginalDatas.size() != sortedDatas.size() )
      return false;
    //check items are same
    for( Number data : orginalDatas )
    {
      boolean equalled = false;
      for( Number sortedData : sortedDatas )
      {
        if( data == sortedData )
        {
          equalled = true;
          break;
        }
      }
      if( !equalled )
        return false;
    }
    
    //check sorted.
    Number preData = null;
    for( Number data : sortedDatas )
    {
      if( preData != null && preData.longValue() > data.longValue() )
      {
        return false;
      }
      preData = data;

    }
    return true;
  }
  
  public static void log( Collection< Number > datas )
  {
    for( Number data : datas )
    {
      log( "" + data + ", " );
    }
    logLine("");
  }
  
  public static void log( String msg )
  {
    System.out.print( msg );
  }
  
  public static void logLine( String msg )
  {
    System.out.println( msg );
  }
}
